package com.example.wxai.controller;

import com.example.wxai.pijo.entity.Chat;
import com.example.wxai.pijo.entity.ChatRequest;
import com.example.wxai.pijo.vo.MessageVo;
import com.example.wxai.result.Result;
import com.example.wxai.service.IChatService;
import com.example.wxai.service.IMessageService;
import com.example.wxai.utils.BeanCopyUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.messages.AbstractMessage;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

@RestController
@Slf4j
@RequestMapping("/chat")
public class ChatController {

    @Resource
    private ChatClient chatClient;

    @Resource
    private InMemoryChatMemory inMemoryChatMemory;
    @Resource
    private IChatService chatService;
    @Resource
    private IMessageService MessageService;


    @PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> streamChat(@RequestBody ChatRequest request) {

        //刚开始聊天
        return chatClient.prompt(request.getMessage())
                .advisors(new MessageChatMemoryAdvisor(inMemoryChatMemory, request.getChatId(), 20), new SimpleLoggerAdvisor())
                .stream().content()
                .map(content -> ServerSentEvent.builder(content).event("message").build())
                .concatWith(Mono.defer(() -> {
                    // 最终保存完整消息
                    return Mono.fromRunnable(() -> {
                        // 6. 后续操作处理
                        log.info("存入数据库{}", inMemoryChatMemory.get(request.getChatId(), 1));
                        chatService.saveAndMessage(request.getUserId(), inMemoryChatMemory.get(request.getChatId(), 2), request.getChatId());
                        //问题回答结速标识,以便前端消息展示处理
                    }).thenReturn(ServerSentEvent.builder("[DONE]").build());
                }))
                .onErrorResume(e -> Flux.just(ServerSentEvent.builder("Error: " + e.getMessage()).event("error").build()))
                ;
    }


    /**
     * 创建新对话
     *
     * @return
     */
    @PostMapping("/add")
    public Result<UUID> addChat() {
        log.info("创建新对话");
        UUID uuid = UUID.randomUUID();
        return Result.success(uuid);
    }

    /**
     * 查询聊天列表
     * @param userId
     * @return
     */
    @GetMapping("/listChat")
    public Result<List<Chat>> listResult(String userId){
        log.info("查询聊天列表{}",userId);
        List<Chat> list = chatService.lambdaQuery().eq(Chat::getUserId, userId).eq(Chat::getIdDelete,false).list();
        return Result.success(list);
    }


    @GetMapping("/getMessage")
    public Result<List<MessageVo>> messageList(String chatId){
        log.info("查询聊天记录{}",chatId);
        List<com.example.wxai.pijo.entity.Message> list = MessageService.lambdaQuery().eq(com.example.wxai.pijo.entity.Message::getChatId, chatId).list();
        //存入缓存
        if (!list.isEmpty()) {
            //存在则组装
            List<Message> messages = new ArrayList<>();
            list.forEach(e -> {
                Message message = null;
                if (e.getMessageType().equals("USER")) {
                    message = new UserMessage(e.getMessage());
                } else {
                    message = new AssistantMessage(e.getMessage());
                }
                messages.add(message);
            });
            inMemoryChatMemory.add(chatId, messages);
        }
        List<MessageVo> messageVos = BeanCopyUtils.copyListProperties(list, MessageVo::new);
        return Result.success(messageVos);
    }
}



